package com.coder4j.starter.tools.util;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

/**
 * 包扫描工具
 * @author Keller
 * @date 2021-11-22 19:44:51
 */
public class ScanClassUtils {

    /**
     * 扫描所有的类
     * @param classLoader 指定的类加载器
     * @param packName 指定的包名
     * @param list 存放class的列表
     * @return
     */
    public static List<Class>  scanClasses(ClassLoader classLoader,String packName,List<Class> list){
        URI url = null ;
        try {
            //从packName中解析本地文件路径
            url = classLoader.getResource(packName.replace(".", "/")).toURI();
        } catch (URISyntaxException e) {
            throw new RuntimeException("未找到本地文件");
        }

        //构建本地文件
        File file = new File(url);

        //如果是目录，扫描目录
        if(file.isDirectory()){
            scanDictionary(classLoader,packName,file,list);
        }else {
            //如果是文件，加载class
            loadClass(classLoader,packName,file,list);
        }
       return list;
    }

    /**
     * 扫描目录
     * @param classLoader 指定的类加载器
     * @param packName 包名
     * @param file 文件
     * @param list class列表
     */
    private static void scanDictionary(ClassLoader classLoader,String packName,File file,List<Class> list){
        //读取目录下所有文件
        File[] files = file.listFiles();
        //空目录不处理
        if(files == null || files.length == 0){
            return ;
        }
        //遍历目录下的文件
        for (File item : files) {
            //如果是目录，继续扫描
            if(item.isDirectory()){
                scanDictionary(classLoader,packName + "." + item.getName(),item,list);
            }else {
                //如果是文件，加载类
                loadClass(classLoader,packName,item,list);
            }
        }
    }

    /**
     * 加载类
     * @param classLoader 指定的类加载器
     * @param packName 包名
     * @param file 文件名
     * @param list class列表
     */
    private static void loadClass(ClassLoader classLoader,String packName,File file,List<Class> list){

        //只处理 .class 结尾的文件
        if(!file.getName().endsWith(".class")){
            return;
        }
        Class<?> clazz = null;
        try {
            //加载类
            clazz = classLoader.loadClass(packName + "." + file.getName().replace(".class", ""));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //放到 class列表
        list.add(clazz);
    }

    public static void main(String[] args){
        List<Class> list = new ArrayList<>();
        list = scanClasses(ScanClassUtils.class.getClassLoader(),"com.coder4j.kellercrm.system",list);
        for (Class item : list) {
            System.out.println(item.getSimpleName());
        }
    }

//    /**
//     * jar包查找
//     * @param packName
//     */
//    private void findClassJar(final String packName){
//        String pathName = packName.replace(".", "/");
//        JarFile jarFile  = null;
//        try {
//            URL url = classLoader.getResource(pathName);
//            JarURLConnection jarURLConnection  = (JarURLConnection )url.openConnection();
//            jarFile = jarURLConnection.getJarFile();
//        } catch (IOException e) {
//            throw new RuntimeException("未找到策略资源");
//        }
//
//        Enumeration<JarEntry> jarEntries = jarFile.entries();
//        while (jarEntries.hasMoreElements()) {
//            JarEntry jarEntry = jarEntries.nextElement();
//            String jarEntryName = jarEntry.getName();
//
//            if(jarEntryName.contains(pathName) && !jarEntryName.equals(pathName+"/")){
//                //递归遍历子目录
//                if(jarEntry.isDirectory()){
//                    String clazzName = jarEntry.getName().replace("/", ".");
//                    int endIndex = clazzName.lastIndexOf(".");
//                    String prefix = null;
//                    if (endIndex > 0) {
//                        prefix = clazzName.substring(0, endIndex);
//                    }
//                    findClassJar(prefix);
//                }
//                if(jarEntry.getName().endsWith(".class")){
//                    Class<?> clazz = null;
//                    try {
//                        clazz = classLoader.loadClass(jarEntry.getName().replace("/", ".").replace(".class", ""));
//                    } catch (ClassNotFoundException e) {
//                        e.printStackTrace();
//                    }
//                    eleStrategyList.add((Class<? extends String>) clazz);
//                }
//            }
//
//        }
//
//    }
}
